"""
Request工具类
"""
import json
import logging
import requests

from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import AnonymousUser
from django.core.cache import cache
from django.urls.resolvers import ResolverMatch
from user_agents import parse
from django.conf import settings

logger = logging.getLogger('django')


def get_request_user(request, authenticate=True):
    """
    获取请求user
    (1)如果request里的user没有认证,那么则手动认证一次
    :param request:
    :param authenticate:
    :return:
    """
    user: AbstractBaseUser = getattr(request, 'user', None)
    if user and user.is_authenticated:
        return user
    return user or AnonymousUser()


def get_request_ip(request):
    """
    获取请求IP
    :param request:
    :return:
    """
    ip = getattr(request, 'request_ip', None)
    if ip:
        return ip
    ip = request.META.get('REMOTE_ADDR', '')
    if not ip:
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[-1].strip()
        else:
            ip = 'unknown'
    return ip


def get_request_data(request):
    """
    获取请求参数
    :param request:
    :return:
    """
    request_data = getattr(request, 'request_data', None)
    if request_data:
        return request_data
    data: dict = {**request.GET.dict(), **request.POST.dict()}
    if not data:
        try:
            body = request.body
            if body:
                data = json.loads(body)
        except Exception as e:
            pass
        if not isinstance(data, dict):
            data = {'data': data}
    return data


def get_request_path(request, *args, **kwargs):
    """
    获取请求路径
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    request_path = getattr(request, 'request_path', None)
    if request_path:
        return request_path
    values = []
    for arg in args:
        if len(arg) == 0:
            continue
        if isinstance(arg, str):
            values.append(arg)
        elif isinstance(arg, (tuple, set, list)):
            values.extend(arg)
        elif isinstance(arg, dict):
            values.extend(arg.values())
    if len(values) == 0:
        return request.path
    path: str = request.path
    for value in values:
        path = path.replace('/' + value, '/' + '{id}')
    return path


def get_request_canonical_path(request, *args, **kwargs):
    """
    获取请求路径
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    request_path = getattr(request, 'request_canonical_path', None)
    if request_path:
        return request_path
    path: str = request.path
    resolver_match: ResolverMatch = request.resolver_match
    for value in resolver_match.args:
        path = path.replace(f"/{value}", "/{id}")
    for key, value in resolver_match.kwargs.items():
        if key == 'pk':
            path = path.replace(f"/{value}", f"/{{id}}")
            continue
        path = path.replace(f"/{value}", f"/{{{key}}}")

    return path


def get_browser(request, *args, **kwargs):
    """
    获取浏览器名
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    ua_string = request.META['HTTP_USER_AGENT']
    user_agent = parse(ua_string)
    browser = user_agent.get_browser()
    if browser == 'Other':
        return ua_string
    return browser


def get_os(request, *args, **kwargs):
    """
    获取操作系统
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    ua_string = request.META['HTTP_USER_AGENT']
    user_agent = parse(ua_string)
    os = user_agent.get_os()
    if os == 'Other':
        return ua_string
    return os


def get_device(request, *args, **kwargs):
    """
    获取操作系统
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    ua_string = request.META['HTTP_USER_AGENT']
    user_agent = parse(ua_string)
    device = user_agent.get_device()
    if device == 'Other':
        return ua_string
    return device


def get_login_location(request, *args, **kwargs):
    """
    获取ip 登录位置
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    # if not getattr(settings, "ENABLE_LOGIN_LOCATION", False): return ""
    request_ip = get_request_ip(request)
    # request_ip = '180.184.220.50'
    # 从缓存中获取
    location = cache.get(request_ip) if getattr(settings, "REDIS_ENABLE", False) else ""
    if location:
        return location
    # 通过api 获取，再缓存redis
    try:
        headers = {"token": "7203860a90b8c1075c48526c9a1972e5"}
        response = requests.get(url="https://api.ip138.com/ip/", params={'ip': request_ip, 'datatype': 'jsonp'},
                                headers=headers)
        location_dict = json.loads(response.text)
        # {"ret":"ok","ip":"139.208.104.228","data":["中国","吉林","延边","和龙","联通","133500","0433"]}
        location = ""

        data_list = location_dict["data"]

        location += data_list[4]

        for i in range(4):
            if data_list[i] != '':
                location += "" + data_list[i]

        if getattr(settings, "REDIS_ENABLE", False):
            cache.set(request_ip, location, 86400)

        logger.info(location)
        return location
    except Exception as e:
        pass
    return ""


def get_login_info(request):
    request_ip = get_request_ip(request)
    try:
        response = requests.get(url="https://qifu-api.baidubce.com/ip/geo/v1/district", params={'ip': request_ip})
    # {"code": "Success",
    #  "data": {"continent": "亚洲", "country": "中国", "zipcode": "215000", "timezone": "UTC+8", "accuracy": "城市",
    #           "owner": "中国联通", "isp": "中国联通", "source": "数据挖掘", "areacode": "CN", "adcode": "320500",
    #           "asnumber": "4837", "lat": "31.313892", "lng": "120.609315", "radius": "72.6375", "prov": "江苏省",
    #           "city": "苏州市", "district": ""}, "charge": false, "msg": "查询成功", "ip": "153.35.127.44",
    #  "coordsys": "WGS84"}
        return response.json()["data"]
    except Exception as e:
        pass
    return {}


def get_weather(request):
    """
    获取天气
    :return:
    """
    request_ip = get_request_ip(request)
    if request_ip == '127.0.0.1':
        return {'ret': 'ok', 'code': 110000, 'province': '上海市', 'city': '宝山区', 'area': '',
                'data': {'time': '2023-02-12 08:20', 'dayIcon': 'https://cache.ip138.com/user/image/tianqi/d06.png',
                         'dayWeather': '雨夹雪', 'dayTemp': '1', 'dayWind': '<3级',
                         'nightIcon': 'https://cache.ip138.com/user/image/tianqi/n01.png', 'nightWeather': '多云',
                         'nightTemp': '-4', 'nightWind': '<3级', 'temp': '1',
                         'Icon': 'https://cache.ip138.com/user/image/tianqi/d06.png', 'weather': '雨夹雪',
                         'wind': '东北风1级',
                         'humidity': '85', 'pm25': '144'}}
    # location = get_login_location(request)
    # request_ip = '180.119.220.50'
    # request_ip = '180.184.220.50'
    # 从缓存中获取
    weather_key = request_ip + "weather"
    weather_dict = cache.get(weather_key) if getattr(settings, "REDIS_ENABLE", False) else ""
    if weather_dict:
        return weather_dict
    # 通过api 获取，再缓存redis
    try:
        headers = {"token": "1edb7c239f80825b51af7c914d8790c6"}
        response = requests.get(url="https://api.ip138.com/weather/", params={'ip': request_ip, 'style': 1},
                                headers=headers)
        weather_dict = json.loads(response.text)
        logger.info(weather_dict)

        if getattr(settings, "REDIS_ENABLE", False):
            cache.set(weather_key, weather_dict, 14400)
        return weather_dict
    except Exception:
        pass
    pass


# de = {'ret': 'ok', 'code': 110000, 'province': '北京市', 'city': '', 'area': '',
#       'data': {'time': '2023-02-12 08:20', 'dayIcon': 'https://cache.ip138.com/user/image/tianqi/d06.png',
#                'dayWeather': '雨夹雪', 'dayTemp': '1', 'dayWind': '<3级',
#                'nightIcon': 'https://cache.ip138.com/user/image/tianqi/n01.png', 'nightWeather': '多云',
#                'nightTemp': '-4', 'nightWind': '<3级', 'temp': '1',
#                'Icon': 'https://cache.ip138.com/user/image/tianqi/d06.png', 'weather': '雨夹雪', 'wind': '东北风1级',
#                'humidity': '85', 'pm25': '144'}}


def get_day_note():
    response = requests.get(url="http://open.iciba.com/dsapi/")
    note_data = json.loads(response.text)
    return note_data


def get_verbose_name(queryset=None, view=None, model=None):
    """
    获取 verbose_name
    :param request:
    :param view:
    :return:
    """
    try:
        if queryset and hasattr(queryset, 'model'):
            model = queryset.model
        elif view and hasattr(view.get_queryset(), 'model'):
            model = view.get_queryset().model
        elif view and hasattr(view.get_serializer(), 'Meta') and hasattr(view.get_serializer().Meta, 'model'):
            model = view.get_serializer().Meta.model
        if model:
            return getattr(model, '_meta').verbose_name
    except Exception as e:
        pass
    return ""


def setCreateUser(data, request):
    data["creator"] = request.user.id
    data["modifier"] = request.user.id
    # return request


def setModifyUser(request):
    request.data["modifier"] = request.user.id
    return request
